﻿// DigitalDesign
// Project: InformationBoard
// Developer: Montak Oleg
// Created: 18.11.2011
// Last change: 18.11.2011
// Description: class DataVersionManager - manages versions of customer data. Singleton.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Server
{

    public enum DataVersionEnum { dvSchedules, dvVideo, dvSettings };

    /// <summary>
    /// Класс для управления версией данных. Singleton.
    /// </summary>
    public class DataVersionManager
    {
        private DataModelContainer _context;

        #region Singleton pattern implementation
        private static readonly DataVersionManager _instance = new DataVersionManager();

        public static DataVersionManager Instance
        {
            get { return _instance; }
        }

        protected DataVersionManager()
        {
            _context = Context.Instance;
        }
        #endregion

        #region Базовый функционал
        /// <summary>
        /// Возвращает общую версию данных клиента. 
        /// Если клиента с переданным Id не существует, выбрасывается исключение.
        /// </summary>
        public int GetDataVersion(int clientId)
        {
            return _context.ClientChanges.Single(c => c.Id == clientId).DataVersion;
        }

        /// <summary>
        /// Возвращает расширенную информацию о версии данных клиента.
        /// </summary>
        public wClientChanx GetDataVersionEx(int clientId)
        {
            var clientChanges = _context.ClientChanges.Single(c => c.Id == clientId);
            return new wClientChanx(clientChanges);
        }

        /// <summary>
        /// Увеличивает(обновляет) версию данных клиента.
        /// В dataParts передаются "части данных", в которых произошли изменения.
        /// </summary>
        public bool IncDataVersion(int clientId, IEnumerable<DataVersionEnum> dataParts)
        {
            if (dataParts.Count() == 0)
                return true;
            try
            {
                var client = _context.ClientChanges.Single(c => c.Id == clientId);

                if (dataParts.Contains(DataVersionEnum.dvSchedules))
                    client.SchedulesDataVersion++;

                if (dataParts.Contains(DataVersionEnum.dvVideo))
                    client.VideoDataVersion++;

                if (dataParts.Contains(DataVersionEnum.dvSettings))
                    client.SettingsDataVersion++;

                _context.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion

        #region Всякие вспомогательные штуки, облегчающие использование класса.
        /// <summary>
        /// Увеличивает версию даннных для списка клиентов
        /// </summary>
        public bool IncDataVersion(IEnumerable<int> clientIds, IEnumerable<DataVersionEnum> dataParts)
        {
            foreach (var clientId in clientIds)
            {
                if (!IncDataVersion(clientId, dataParts))
                    return false;
            }
            return true;
        }

        /// <summary>
        /// Увеличивает версию даннных для клиентов, зависящих от расписания scheduleNode
        /// </summary>
        public bool IncSchedulesVersion(Schedule scheduleNode)
        {
            var dataParts = new List<DataVersionEnum>() { DataVersionEnum.dvSchedules };
            return IncDataVersion(scheduleNode.Location.ClientDevices.Select(c => c.Id).ToList(), dataParts);
        }

        /// <summary>
        /// Увеличивает версию даннных для клиентов, зависящих от изменений в расписании
        /// </summary>
        public bool IncSchedulesVersion(ScheduleChanx changeNode)
        {
            var dataParts = new List<DataVersionEnum>() { DataVersionEnum.dvSchedules };
            return IncDataVersion(changeNode.Location.ClientDevices.Select(c => c.Id).ToList(), dataParts);
        }

        /// <summary>
        /// Обновить версию настроек
        /// </summary>
        public bool IncSettingsVersion(int clientId)
        {
            return IncDataVersion(clientId, new List<DataVersionEnum>() { DataVersionEnum.dvSettings });
        }

        /// <summary>
        /// Обновить версию видео
        /// </summary>
        public bool IncVideoVersion(int clientId)
        {
            return IncDataVersion(clientId, new List<DataVersionEnum>() { DataVersionEnum.dvVideo });
        }
        #endregion
    }
}
